package services

import (
    "sync"
    "time"
    "github.com/beego/beego/v2/core/logs"
    "fmt"
    "net/smtp"
)

type AlertService struct {
    mu           sync.RWMutex
    alertHistory map[string][]Alert
    handlers     []AlertHandler
}

type Alert struct {
    ID        string    `json:"id"`
    Type      string    `json:"type"`
    Level     string    `json:"level"`
    Message   string    `json:"message"`
    Resource  string    `json:"resource"`
    Value     float64   `json:"value"`
    Threshold float64   `json:"threshold"`
    Time      time.Time `json:"time"`
    Status    string    `json:"status"` // active, resolved
}

type AlertHandler interface {
    HandleAlert(alert Alert) error
}

// Email告警处理器
type EmailAlertHandler struct {
    SMTPServer  string
    SMTPPort    int
    SMTPUser    string
    SMTPPass    string
    ToAddresses []string
}

func (h *EmailAlertHandler) HandleAlert(alert Alert) error {
    addr := fmt.Sprintf("%s:%d", h.SMTPServer, h.SMTPPort)
    auth := smtp.PlainAuth("", h.SMTPUser, h.SMTPPass, h.SMTPServer)
    
    msg := fmt.Sprintf("From: %s\r\n"+
        "To: %s\r\n"+
        "Subject: Alert: %s\r\n"+
        "\r\n"+
        "%s\r\n",
        h.SMTPUser,
        h.ToAddresses[0],
        alert.Type,
        alert.Message)

    return smtp.SendMail(addr, auth, h.SMTPUser, h.ToAddresses, []byte(msg))
}

// Webhook告警处理器
type WebhookAlertHandler struct {
    url     string
    headers map[string]string
}

func NewAlertService() *AlertService {
    return &AlertService{
        alertHistory: make(map[string][]Alert),
        handlers:     make([]AlertHandler, 0),
    }
}

func (as *AlertService) AddHandler(handler AlertHandler) {
    as.handlers = append(as.handlers, handler)
}

func (as *AlertService) TriggerAlert(alert Alert) {
    as.mu.Lock()
    defer as.mu.Unlock()

    // 记录告警历史
    if _, exists := as.alertHistory[alert.Resource]; !exists {
        as.alertHistory[alert.Resource] = make([]Alert, 0)
    }
    as.alertHistory[alert.Resource] = append(as.alertHistory[alert.Resource], alert)

    // 调用所有处理器
    for _, handler := range as.handlers {
        go handler.HandleAlert(alert)
    }

    // 记录告警日志
    logs.Warning("Alert triggered: [%s] %s - %s", alert.Level, alert.Type, alert.Message)
}

func (as *AlertService) ResolveAlert(alertID string, resource string) {
    as.mu.Lock()
    defer as.mu.Unlock()

    if alerts, exists := as.alertHistory[resource]; exists {
        for i := range alerts {
            if alerts[i].ID == alertID {
                alerts[i].Status = "resolved"
                break
            }
        }
    }
}

func (as *AlertService) GetAlerts(resource string) []Alert {
    as.mu.RLock()
    defer as.mu.RUnlock()

    if alerts, exists := as.alertHistory[resource]; exists {
        return alerts
    }
    return nil
}
